/*
 * @Descripttion: 
 * @Author: ziwei
 * @Date: 2022-07-07 13:42:37
 * @LastEditors: ziwei
 * @LastEditTime: 2022-07-07 14:34:50
 */
export {}
interface A{
    a:string
    b:number
    c:boolean
}
type Partial<T> = {
    [P in keyof T]?:T[P]
}
type PartialA = Partial<A>

interface Company{
    id:number;
    name:string
}
interface Person{
    id:number
    name:string
    company:Company
}
//递归变成可选项
type DeepPartial<T> = {
    [U in keyof T]?:T[U] extends object?DeepPartial<T[U]>:T[U]
}
type PartialPerson = DeepPartial<Person>
let p:PartialPerson = {
    id:1,
    name:'xx',
    company:{}
}

//可选变成必选
namespace namespaceA{
    interface Person{
        name:string;
        age?:number
    }
    type Required<T> = {
        [P in keyof T]-?: T[P];
    };
    type RequiredPerson = Required<Person>
    let p:RequiredPerson={
        name:'xx',
        age:11
    }
}

//Readonly
namespace namespaceB{
    interface Person{
        name:string;
        age?:number
    }
    type Readonly<T> = { readonly [P in keyof T]: T[P]; }
    type ReadOnlyPerson = Readonly<Person>
    
    let p:ReadOnlyPerson = {
        name:'zz',
        age:11
    }
    // p.name = 'yy'
    // p.age = 11
}

//pick 筛选某一项返回
 namespace namespaceC{
    interface Person{
        name:string;
        age:number
        gender:number
    }
    let person:Person = {
        name:'xx',
        age:11,
        gender:1
    }
    type KeyOfPerson = keyof Person;//nage|age|gender 字面量类型
    type Pick<T, K extends keyof T> = {
        [P in K]: T[P];
    };
    type PickPerson = Pick<Person,'name'|'age'>

    //Extract 提取
    type Extract<T,U> = T extends U?T:never
    //有条件类型分发 裸类型分发
    type E = Extract<string|number|boolean,string|number>
    let e:E = '1'
}

namespace namespaceD{
    type KeyOfAny = keyof any
    type Record<K extends keyof any, T> = {
        [P in K]: T;
        //[]表示任意类型
        //[key:string]:string
        //[key:number]:string
    };
    let K:Record<string|number,string> = {name:'zz',age:'11'}
    //Record 所有属性值映射到另一
    function mapObject<K extends string|number,T,U>(obj:Record<K,T>,map:(x:T)=>U){
        let result:Record<K,U> = <Record<K,U>>{}
        for(const key in obj){
            result[key] = map(obj[key])
        }
        return result
    }
    let obj = {count1:1,cunt2:2,3:3}
    let map = (x:number)=>x*2+''
    let newObj = mapObject<string|number,number,string>(obj,map) //{count1,count2:4}

}
